import hashlib
import json
import time
from datetime import datetime
import logging
import os
from json import JSONDecodeError
from requests import request
from .base_client import BaseClient
from .exceptions import ApiException
from .get_auth_code import generate_authcode
from .get_auth_code_v2 import generate_authcode_v2


class Client(BaseClient):

    def __init__(
            self,
            app_key=None,
            app_secret=None,
            timeout=None,
            verify=True,
            show_info=None,
    ):
        self.app_key = app_key
        self.app_secret = app_secret
        # self._auth = AuthCode(app_key=app_key)
        self.timeout = timeout
        self.verify = verify
        self.show_info = show_info

    @property
    def headers(self):
        return {
            'content-type': 'application/json'
        }

    def _check_version(self, path):
        if "<version>" not in path:
            return '/'+self.version+path
        return path.replace("<version>", self.version)

    def _get_authcode(self, data, req_time):
        # return generate_authcode(self.app_key, self.app_secret, req_time, data)
        return generate_authcode_v2(self.app_key, self.app_secret, req_time, data)

    def _get_payload(self, data, req_time):
        return {
            "reqTime": req_time,  # 时间戳需与生成authcode时一致
            # "req_time": req_time,  # 时间戳需与生成authcode时一致
            "data": data,
            "appKey": self.app_key  # 需与生成authcode时的appKey一致
        }

    def _request(
            self,
            path: str,
            *,
            data: None,
            headers=None,
            res_no_data: bool = False,
            bulk: bool = False,
            wrap_list: bool = False,
    ):
        params = {}
        if data is None:
            data = {}
        req_time = str(int(time.time()))
        params['authcode'] = self._get_authcode(data['data'], req_time)
        payload = self._get_payload(data['data'], req_time)
        if self.show_info:
            print("HTTP Method: %s", self.method)
            print("Making request to URL: %s", self.endpoint + self._check_version(path))
            print("Request Params: %s", params)
            print("Request Data: %s", json.dumps(payload))
            print("Request Headers: %s", headers or self.headers)

        res = request(
            "POST",
            self.endpoint + self._check_version(path),
            params=params,
            json=payload,
            headers=headers or self.headers,
            timeout=self.timeout,
            verify=self.verify,
        )
        return self._check_response(res, res_no_data, bulk, wrap_list)

    def _check_response(
            self,
            res,
            res_no_data: bool = False,
            bulk: bool = False,
            wrap_list: bool = False,
    ):
        if res.status_code != 200:
            raise ApiException(error={
                'code': res.status_code,
                'message': '请求异常'})
        try:
            js = res.json() or {}
        except JSONDecodeError:
            raise ApiException(error={
                'message': '无法解析Jason'})
        if self.show_info:
            print("Response before list handling: %s", js)
        code = js['code']

        if code != 200:
            raise ApiException(js)
        else:
            return js
